<h2>GeDA - Generic DTO Assembler</h2>
<p><img src="/uploads/files/logo.png" border="0" alt="GeDA logo"
	title="GeDA logo" align="right" />GeDA was inspired by developer's
lazyness (as always). The rationale for its existance was overhead of
creating DTO Assemblers in an n-tier application to pass information
within domain object to UI through DTO's (Data Transfer Objects). The
basic principle of the above application design is to extract the
necessary information from the domain objects in the form of DTO's. In
reality this involves a tidious get/set method calls that look very much
the same for most of the objects. GeDA uses Java5's annotations in order
to map DTO's onto paths of the Domain object properties (the reflection
method). Thus the annotated DTO's can be examined by a Generic DTO
Assembler that will create specific instance of the assembler for the
DTO is respect to a Domain object. The assmebler is basically a
placeholder for so called "data pipes" that allow transferring data
from/to domain object's field. But do not take my word for it - try it
out yourself.</p>
<p><span style="color: #ff0000;"><strong>NOTE:
Unfortunatelly I do not always have time to update the documentation, so
please look into JUnit tests in the test source - these will be the best
guides.&nbsp; <br />
</strong></span></p>
<p>web: <a title="GeDA"
	href="https://sourceforge.net/projects/geda-genericdto/">https://sourceforge.net/projects/geda-genericdto/</a></p>
<p>svn: svn co
https://geda-genericdto.svn.sourceforge.net/svnroot/geda-genericdto
geda-genericdto</p>
<p>contact us (for any reason :-)): using out feedback <a
	title="Feedback form" href="/en/feedback.html">form</a></p>
<p>Recent enhancements:</p>
<p><strong>2010-01-31</strong> Default field binding and inheritance
of DTO' fix</p>
<p><strong>2010-01-28</strong> Collections support and enhanced bean
factory management (added DTO factory injection)</p>
<p><strong>2009-10-21</strong> Few enhancements with value
converters and bean factory injections</p>
<p><strong>2009-10-08</strong> Initial GeDA pilot that allows domain
entities to flat DTO conversions</p>
<h1>Learn by Example:</h1>
<p>Say we have a web-application that in some of its part manages
the user details. So we have a domain object Person in which we have a
domain object Address. On the other hand we have a web-page called "edit
user info" where we wish to input the name and address details and
submit it to the server.</p>
<p>So here is what we have:</p>
<p><strong>Person:</strong></p>
<pre class="java">
package dp.lib.dto.geda.example;

public class Person {

    private Long personId;
    private String name;
    private Address address;


    public Long getPersonId() {
        return personId;
    }
    public void setPersonId(Long personId) {
        this.personId = personId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }

}
</pre>
<p><strong>Address:</strong></p>
<pre class="java">
package dp.lib.dto.geda.example;

public class Address {

    private String street;
    private String city;

    public String getStreet() {
        return street;
    }
    public void setStreet(String street) {
        this.street = street;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }

}
</pre>
<p>&nbsp;</p>
<p><strong>The DTO (Form data):</strong></p>
<pre class="java">
package dp.lib.dto.geda.example;

import dp.lib.dto.geda.annotations.Dto;
import dp.lib.dto.geda.annotations.DtoField;

@Dto
public class PersonDTO {


    @DtoField("personId")
    private Long personId;
    @DtoField("name")
    private String name;
    @DtoField("address.street")
    private String street;
    @DtoField("address.city")
    private String city;

    public Long getPersonId() {
        return personId;
    }
    public void setPersonId(Long personId) {
        this.personId = personId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getStreet() {
        return street;
    }
    public void setStreet(String street) {
        this.street = street;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }

}
</pre>
<p>So you can see that we have mapped our DTO fields to out
Person+Address domain objects.</p>
<p>"What now?" I hear you saying. Well we need say PersonService
that will provide our DTO wheneven our web-app needs it. Here is what it
may look like:</p>
<p><strong>PersonService:</strong></p>
<pre class="java">
package dp.lib.dto.geda.example;

public class PersonService {


    public PersonDTO getPersonInfo(final Long personId) {
        final Person person = getPersonFromDb(personId);
        final PersonDTO dto = newBean();

        final DTOAssembler assembler = DTOAssembler.newAssembler(PersonDTO.class, Person.class);
        assembler.assembleDto(dto, person, null);

        return dto;
    }

    public PersonDTO newBean() {
        return new PersonDTO();
    }

    public Person getPersonFromDb(final Long personId) {
        // some code to return a domain object
    }

}
</pre>
<p>&nbsp;</p>
<p>Neat eh? So step by step:</p>
<p>1. We retrieved the Person domain object from DB</p>
<p>2. We created new DTO bean (This is better to be done through
bean factory)</p>
<p>3. We created the assembler instance</p>
<p>4. we assembled the DTO</p>
<p>And what was done behind the sceenes (step 3):</p>
<p>1. The assembler cache was checked for existance of the assembler
(the cache is used to optimise performance, but point to note is that
there will be only one instance of assembler for a DTO - Domain pair)</p>
<p>2. A new instance of assembler is created and the DTO is examined
with Domain object class to create "data pipes". In reality all the
assembler is - is a collection of data pipes that transfer data from/to
domain object. Each pipe is designated to one field of domain object.</p>
<p>3. The assembler instance is created and cached.</p>
<p>&nbsp;</p>
<p>Ok, so while we were examining the code our user has altered the
infor in web-form and posted it, so how will our PersonService will
handle the post:</p>
<p>&nbsp;</p>
<pre class="java">
public class PersonService {

    ...

    public void savePersonInfo(final PersonDTO dto) {

        final Person person = getPersonFromDb(dto.getPersonId());

        final DTOAssembler assembler = DTOAssembler.newAssembler(PersonDTO.class, Person.class);
        assembler.assembleEntity(dto, person, null);

        saveEntity(person);

    }

    private void saveEntity(final Person person) {
        // do the db saving stuff
    }

    ...

}
</pre>
<p>Lets have a close look:</p>
<p>1. We retrieve a fresh domain object</p>
<p>2. We create the assemble (No we are not, we are using the cached
one, since we provide the same DTO-Domain pair)</p>
<p>3. do the assembly</p>
<p>4. persist the changes</p>
<p>&nbsp;</p>
<p>Well there is all that is to it... ehh - nope. As you can see
each of the assemly methods has a third parameter which is a map of
value converters. GeDA declares a <span style="color: #800000;">ValueConverter</span>
- that is used to define the converters. In our simple example above all
data in DTO and Domain match their type, so all is nice and simple, but
if we have some complex data in the domain? That is were the converters
come into play.</p>
<p>To declare a converter you need to specify it in the field
annotation:</p>
<p>For example we have an enum that needs to be a boolean in our DTO</p>
<pre class="java">
    /**
     * Test enum for conversion testing.
     */
    public enum Decision { 
        /** true. */
        Decided, 
        /** false. */
        Undecided 
    };

    @Field(value = "decision", converter = "boolToEnum")
    private Decision myEnum;
</pre>
<p>And here is the Converter:</p>
<pre class="java">
class TestConverter3 implements ValueConverter {

    public Object convertToDto(final Object object) {
        final Boolean value = (Boolean) object;
        if (value != null && value) {
            return Decision.Decided;
        }
        return Decision.Undecided;
    }

    public Object convertToEntity(final Object object) {
        final Decision value = (Decision) object;
        return (value != null && Decision.Decided.equals(value));
    }

}
</pre>
<p>&nbsp;</p>
<p>And here is how we can use it:</p>
<pre class="java">
       final Map converters = new HashMap();
        converters.put("boolToEnum", conv3toDto);

        final DTOAssembler assembler = 
            DTOAssembler.newAssembler(TestDto3Class.class, TestEntity3Class.class);

        assembler.assembleDto(dto, entity, converters);

        assertEquals(Decision.Decided, dto.getMyEnum());
</pre>
<p>So we need to assign the same key so that assembler know which
converter in our map of converters to use. This gives great flexibility
since you can reuse the same converter for many fields BUT the point to
note the converters, since they are reused MUST be stateless, this is
one of the reasons why they were designed to be a parameter on the
conversion method - to enforce this idea.</p>
<p>&nbsp;</p>
<p>The last feature that I want to talk about is the read only
fields - sometimes the DTO is used for read only information or some of
its fields. To let the assembler know this you can use the Field
annotation in the following way:</p>
<pre class="java">
	@DtoField(value = "number", readOnly = true)
    private Double myDouble;
</pre>
<p>What this will do is create a one way pipe for the field, meaning
that when you call assebleDto all data from domain object will be copied
to it but when you call assembleEntity only readOnly = false fields will
be copied from DTO back to Entity. This is a nice feature to give you
that extra notch of control over things.</p>
<p>&nbsp;</p>
<p>Hope you enjoyed reading this as much as I have writting it. But
I thing the best way to learn it is to download the source and examin
the JUnit test - this will show various ways of how to use GeDA.</p>
<p>All the best to you and hope GeDA will save you some time in your
projects.</p>
<p>&nbsp;</p>
<p>If you have any questions / suggestions / bug reports please send
them to us using the feedback <a title="Feedback form"
	href="/en/feedback.html">form</a>.</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>